﻿using System.Collections.Generic;
using Cms.Application;
using Cms.Application.IO;
using Cms.Domain;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Cms.Tests.Unit.Application
{
    [TestClass]
    public class FileReferencesManagerTests : BasePresenterTests
    {
        private Administrator _administrator;
        private Mock<IDiskAccess> _diskAccessMock;
        private IList<SourceCodeVersion> _sourceCodeVersions;
        private MediaFile _file;
        private FileReferencesManager _frm;
        private Site _site;

        [TestMethod]
        public void UpdateFileReferences_OneFileIsRenamed_CssBackgroundIsUpdatedWithNewPath()
        {
            PrepareTest();
            string originalVirtualPath = "media/body-bg.png";
            string originalCss = "body { margin: 0px; background-image: url(/media/body-bg.png); padding: 0px; }";
            string expectedCss = "body { margin: 0px; background-image: url(/media/new-body-bg.png); padding: 0px; }";
            _file.Name = "new-body-bg.png";
            string actualCss = GetCssAfterUpdate(originalCss, originalVirtualPath);
            Assert.AreEqual(expectedCss, actualCss);

            originalCss = "body {background:#ffffff url('../media/body-bg.png') no-repeat right top;}";
            expectedCss = "body {background:#ffffff url('../media/new-body-bg.png') no-repeat right top;}";
            _file.Name = "new-body-bg.png";
            actualCss = GetCssAfterUpdate(originalCss, originalVirtualPath);
            Assert.AreEqual(expectedCss, actualCss);
        }

        [TestMethod]
        public void RemoveFileReferences_OneFileIsRemoved_CssBackgroundIsUpdatedWithNone()
        {
            PrepareTest();
            string originalCss = "body { margin: 0px; background-image: url(/media/body-bg.png); padding: 0px; }";
            string expectedCss = "body { margin: 0px; background-image: none; padding: 0px; }";
            _file.Name = "body-bg.png";
            string actualCss = GetCssAfterDelete(originalCss);
            Assert.AreEqual(expectedCss, actualCss);

            originalCss = "body {background:#ffffff url('../media/body-bg.png') no-repeat right top;}";
            expectedCss = "body {background:#ffffff none no-repeat right top;}";
            _file.Name = "body-bg.png";
            actualCss = GetCssAfterDelete(originalCss);
            Assert.AreEqual(expectedCss, actualCss);
        }

        private void PrepareTest()
        {
            _site = new Site() { ID = 1, RootMediaFolder = "media" };
            _administrator = new Administrator() { ID = 1, CurrentSite = _site };
            _diskAccessMock = new Mock<IDiskAccess>();
            InitRepositoryFactoryMock();
            SourceCode sourceCode = new SourceCode() { ID = 1, Site = _site };
            _sourceCodeVersions = new List<SourceCodeVersion> { new SourceCodeVersion() { Parent = sourceCode } };
            _file = new MediaFile() { ID = 1, Folder = null, Site = _site };
            _frm = new FileReferencesManager(_administrator, SiteRepositoryMock.Object, ContentRepositoryMock.Object, _diskAccessMock.Object);
        }

        private void PrepareGetCss()
        {
            ContentRepositoryMock.Setup(m => m.GetContentWithReferencesTo(It.IsAny<string>(), It.IsAny<int>())).Returns(new List<ContentTranslationVersion>());
            SiteRepositoryMock.Setup(m => m.GetSourceCodeWithReferencesTo(It.IsAny<string>(), _site.ID)).Returns(_sourceCodeVersions);
        }

        private string GetCssAfterUpdate(string originalCss, string originalVirtualPath)
        {
            PrepareGetCss();
            _sourceCodeVersions[0].Code = originalCss;
            _frm.UpdateFileReferences(originalVirtualPath, _file.GetVirtualPath(), _administrator.CurrentSite.ID);
            return _sourceCodeVersions[0].Code;
        }

        private string GetCssAfterDelete(string originalCss)
        {
            PrepareGetCss();            
            _sourceCodeVersions[0].Code = originalCss;
            _frm.RemoveFileReferences(_file.GetVirtualPath(), _administrator.CurrentSite.ID);
            return _sourceCodeVersions[0].Code;
        }
    }
}
